<!--
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
-->
<html>
  <head>
    <script>
    var CEOD_URL = ("https://computeengineondemand.appspot.com/turn?" +
                    "username=1234&key=5678");
    var xmlhttp = null;
    var turnServers = [];  // Array of {turnUri, username, password}.
    // The next two arrays' entries correspond 1:1 to turnServers.
    var gotTurn = [];  // Entries are null (not done), "PASS", or "FAIL"
    var pcs = [];  // Entries are RTCPeerConnection objects.

    // Test is done; log & replace document body with an appropriate message.
    function finish(msg) {
      msg = "DONE: " + msg;
      console.log(msg);
      document.body.innerHTML = msg;
    }

    // Handle created offer SDP.
    function offerHandler(i, c) {
      var pc = pcs[i];
      pc.setLocalDescription(c,
                             function() {},
                             function(e) {console.log("sLD error: " + e); });
      pc = null;
    }

    // Handle SDP offer creation error.
    function offerError(i, e) {
      console.log("createOffer error: " + e);
      checkForCompletion(i, "FAIL (offerError)");
    }

    // Register a terminal condition |msg| for the |index|'th server and
    // terminate the test with an appropriate message if all servers are done.
    function checkForCompletion(index, msg) {
      gotTurn[index] = msg;
      var pass = true;
      for (var i = 0; i < gotTurn.length; ++i) {
        if (!gotTurn[i])
        return;
        if (gotTurn[i] != "PASS") {
          pass = false;
          // Don't "break" because a later still-null gotTurn value should let
          // us wait more.
        }
      }
      if (pass) {
        finish("PASS");
      } else {
        finish("FAIL: " + JSON.stringify(gotTurn));
      }
    }

    // Make sure we don't wait forever for TURN to complete.
    function nanny(i) {
      if (!gotTurn[i]) {
        checkForCompletion(i, "FAIL (TURN server failed to respond)");
      }
    }

    // Handle incoming ICE candidate |c| from |turnServers[i]|.
    function onIceCandidate(i, c) {
      var pc = pcs[i];
      if (!c || !c.candidate) {
        checkForCompletion(
          i, !gotTurn[i] ? "FAIL (no TURN candidate)" :
                           (gotTurn[i] == "PASS") ? "PASS" : gotTurn[i]);
        return;
      }

      if (c.candidate.candidate.indexOf(" typ relay ") >= 0) {
        gotTurn[i] = "PASS";
      }
    }

    // Kick off the test.
    function go() {
      xmlhttp = new XMLHttpRequest();
      xmlhttp.onreadystatechange = onTurnResult;
      xmlhttp.open('GET', CEOD_URL, true);
      xmlhttp.send();
    }

    // Handle the XMLHttpRequest's response.
    function onTurnResult() {
      if (xmlhttp.readyState != 4)
      return;

      if (xmlhttp.status != 200) {
        finish("FAIL (no TURN server)");
        return;
      }

      var turnServer = JSON.parse(xmlhttp.responseText);
      for (i = 0; i < turnServer.uris.length; i++) {
        if (turnServer.uris[i].indexOf(":3479?") >= 0) {
          // Why does CEOD vend useless port 3479 URIs?
          continue;
        }
        console.log("Adding to test: " +
                    [turnServer.uris[i], turnServer.username,
                     turnServer.password]);
        gotTurn.push(null);
        pcs.push(new webkitRTCPeerConnection({
          "iceServers": [{
            "url": turnServer.uris[i],
            "username": turnServer.username,
            "credential": turnServer.password
          }]
        }));
        var index = pcs.length - 1;
        var pc = pcs[index];
        if (!pc) {
          checkForCompletion(index, "FAIL (PeerConnection ctor failed)");
          continue;
        }
        pc.onicecandidate = (
          function(p) { return function(c) { onIceCandidate(p, c); } })(index);
        pc.createOffer(
          (function(p) { return function(o) { offerHandler(p, o); } })(index),
          (function(p) { return function(e) { offerError(p, e); } })(index),
          {'mandatory': { 'OfferToReceiveAudio': true } });
        window.setTimeout(
          (function(p) { return function() { nanny(p); } })(index), 10000);
      }
    }
    </script>
  </head>
  <body onload="go()">
  </body>
</html>
